package com.tanhua.server.service;

import com.tanhua.domain.db.Answer;
import com.tanhua.domain.db.Option;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.DimensionVo;
import com.tanhua.domain.vo.ExaminationVo;
import com.tanhua.domain.vo.SoulQuestionVo;
import com.tanhua.domain.vo.SoulReportVo;
import com.tanhua.dubbo.api.*;
import com.tanhua.server.interceptor.UserHolder;

import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class SoulService {

    @Reference
    private ExaminationApi examinationApi;

    @Reference
    private SoulQuestionApi soulQuestionApi;

    @Autowired
    private RedisTemplate redisTemplate;

    @Reference
    private UserLevelApi userLevelApi;

    @Reference
    private UserSoulReportApi userSoulReportApi;

    @Reference
    private SoulReportApi soulReportApi;

    @Reference
    private DimensionApi dimensionApi;

    @Reference
    private UserInfoApi userInfoApi;

    /**
     * 测灵魂-问卷列表
     */
    public ResponseEntity<Object> testSoul() {
        //获取用户id
        Long userId = UserHolder.getUserId();
        //查询试卷类型
        List<Examination> examintionList = examinationApi.findAllExamination();
        //创建vo集合
        ArrayList<ExaminationVo> voList = new ArrayList<>();
        for (Examination examination : examintionList) {
            // 创建vo类
            ExaminationVo vo = new ExaminationVo();
            //封装试卷相关数据
            BeanUtils.copyProperties(examination, vo);
            vo.setId(examination.getId().toString());

            //获取user的等级
            UserLevel userLevel = userLevelApi.findByUid(userId);


            if (examination.getLevel().equals("初级")) {
                vo.setIsLock(0);
            } else if (examination.getLevel().equals("中级") && userLevel.getLevel() >= 2) {
                vo.setIsLock(0);
            } else if (examination.getLevel().equals("高级") && userLevel.getLevel() >= 3) {
                vo.setIsLock(0);
            } else {
                vo.setIsLock(1);
            }
          /* if (examination.getLevel().equals("初级")) {
                UserSoulReport soulReport = userSoulReportApi.findByUid(userId);
                vo.setReportId(soulReport.getTestReport1());
            } else if (examination.getLevel().equals("中级")) {
                vo.setReportId(userSoulReportApi.findByUid(userId).getTestReport2());
            } else if (examination.getLevel().equals("高级")) {
                vo.setReportId(userSoulReportApi.findByUid(userId).getTestReport3());
            }*/

            UserSoulReport userSoulReport = userSoulReportApi.findByUid(userId);
            switch (examination.getLevel()){

              case "初级":
                  String testReport1 = userSoulReport.getTestReport1();
                  if(testReport1!=null&& testReport1.length()>0){
                      vo.setReportId(userSoulReport.getTestReport1());
                  }
                  break;
              case "中级":
                  String testReport2 = userSoulReport.getTestReport2();
                  if(testReport2!=null&&testReport2.length()>0){
                      vo.setReportId(testReport2);
                  }
                  break;

              case "高级":
                  String testReport3 = userSoulReport.getTestReport3();
                  if(testReport3!=null&&testReport3.length()>0){
                      vo.setReportId(testReport3);
                  }
                  break;

          }
            //查出所有问题的题目
            List<SoulQuestion> questions = soulQuestionApi.findQuestionByEid(examination.getId().toString());
            // List<SoulQuestion> questions = soulQuestionApi.findQuestionAll();
            //创建一个volist，封装给试卷的题目集合
            ArrayList<SoulQuestionVo> soulQuestionVos = new ArrayList<>();
            //遍历查询得到的题目文字
            for (SoulQuestion question : questions) {
                //创建一个新的题目对象用于添加到voList封装试卷
                SoulQuestionVo questionvo = new SoulQuestionVo();
                //将原本的题目文字和id等拷贝到新的题目对象
                BeanUtils.copyProperties(question, questionvo);
                questionvo.setId(question.getId().toString());
                //创建一个选项对象集合，用于封装到新题目对象中
                ArrayList<Option> options = new ArrayList<>();
                //从redis中查询ABCD...各个选项的文字
                Map<String, String> entries = redisTemplate.opsForHash().entries("QUESTION_" + examination.getStar() + "_" + question.getQid());
                //获取所有选项文字的键值对
                Set<Map.Entry<String, String>> set = entries.entrySet();
                //循环遍历键值对，且封装到选项对象中
                for (Map.Entry<String, String> stringStringEntry : set) {
                    //创建一个选项对象，如一个选项对象仅仅代表一个A或B或C
                    Option option = new Option();
                    //封装选项的文字
                    option.setId(stringStringEntry.getKey());
                    option.setOption(stringStringEntry.getValue());
                    //将选项添加到选项集合中，即选项集合就存入当前题目的所有选项
                    options.add(option);
                }
                //将所有选项（选项List）封装到题目对象中
                questionvo.setOptions(options);
                //将题目添加到题目集合中，即题目集合就存入当前试卷的所有题目
                soulQuestionVos.add(questionvo);
            }
            //将所有题目（题目List）封装到试卷对象中
            vo.setQuestions(soulQuestionVos);
            //将所有试卷封装到试卷集合返回给前端
            voList.add(vo);
        }
        return ResponseEntity.ok(voList);
    }

    /**
     * 测灵魂-提交问卷
     */
    public ResponseEntity<Object> submitTestSoul(List<Answer> answers) {
        //查询是那一份试卷
        Answer answer = answers.get(0);
        //查出问题对象，对象中有对应试卷的id
        SoulQuestion soulQuestion = soulQuestionApi.findQuestionById(new ObjectId(answer.getQuestionId()));

        Examination examination = examinationApi.findExaminationById(new ObjectId(soulQuestion.getEid()));
        //获取试卷的星级用于查询答案的分数
        Integer star = examination.getStar();
        //用户的测试分数
        Integer userScore = 0;
        for (Answer userAnswer : answers) {
            //获取题目的Qid
            SoulQuestion question = soulQuestionApi.findQuestionById(new ObjectId(userAnswer.getQuestionId()));
            //获取这一题的每个选项的分数
            Map<String, Integer> entries = redisTemplate.opsForHash().entries("SCORE_" + star + "_" + question.getQid());
            //通过选项编号（即ABCD）获取该选项的分数
            Integer score = entries.get(userAnswer.getOptionId());
            //计算用户分数
            userScore += score;
        }
        String type = null;
        if (userScore < 21) {
            type = "猫头鹰";

        } else if (userScore <= 40) {
            type = "白兔型";
        } else if (userScore <= 55) {
            type = "狐狸型";
        } else {
            type = "狮子型";
        }
        SoulReport report = soulReportApi.findReportByType(type);

        //将用户的报告存在用户的历史最新报告中
        userSoulReportApi.updateUserReport(UserHolder.getUserId(), star, report.getId().toString());
        String string = report.getId().toString();
        //升级用户等级
        //判断试卷等级和用户等级
        Long userId = UserHolder.getUserId();
        UserLevel userLevel = userLevelApi.findByUid(userId);
        Integer level = userLevel.getLevel();

        switch (star){
            case 2:
                if(level==1){
                    //升级
                    userLevelApi.updateUserLevel(userId,2);
                }
                break;
            case 3:
                if(level==2){
                    //升级
                    userLevelApi.updateUserLevel(userId,3);
                }
                break;
        }
        return ResponseEntity.ok(string);
    }


    /**
     * 测灵魂-查看结果
     */
    public ResponseEntity<Object> showReport(String reportId) {
        SoulReportVo vo = new SoulReportVo();
        //通过报告id查询报告的结果
        SoulReport soulReport = soulReportApi.findReportById(reportId);
        //封装报告结果
        vo.setConclusion(soulReport.getText());
        //封装报告图片
        vo.setCover(soulReport.getCover());

        //维度
        Dimension dimension = dimensionApi.findDimensionByUid(UserHolder.getUserId());

        List<DimensionVo> dimensionVos = this.saveDimensions(dimension);

        vo.setDimensions(dimensionVos);

        //通过userid查询用户的历史报告，利用用一份试卷得出同样类型报告的人推荐
        UserSoulReport userSoulReport = userSoulReportApi.findByUid(UserHolder.getUserId());
        //查询与用户统一鉴定结果的人
        List<Long> recommendUserId = userSoulReportApi.findUserByConclusion(userSoulReport);


        List<UserInfo> userInfos = userInfoApi.findByIdListForReport(recommendUserId, UserHolder.getUserId());
        vo.setSimilarYou(userInfos);


        return ResponseEntity.ok(vo);
    }



    //封装维度的方法
    private List<DimensionVo> saveDimensions(Dimension dimension){
        ArrayList<DimensionVo> dimensions = new ArrayList<>();
        String[] strings = new String[]{"外向","判断","抽象","理性"};
        for (int i = 0; i < 4; i++) {
            DimensionVo dimensionVo = new DimensionVo();
            dimensionVo.setKey(strings[i]);
            switch (i){
                case 1:
                    dimensionVo.setValue(dimension.getOutward());
                    break;
                case 2:
                    dimensionVo.setValue(dimension.getEstimate());
                    break;
                case 3:
                    dimensionVo.setValue(dimension.getAbstraction());
                    break;
                case 4:
                    dimensionVo.setValue(dimension.getSense());
                    break;
            }
            dimensions.add(dimensionVo);

        }

        return dimensions;
    }
}
